package com.xhlj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhlj.entity.Comment;
import com.xhlj.entity.Post;
import com.xhlj.mapper.CommentMapper;
import com.xhlj.service.PostService;
import com.xhlj.mapper.PostMapper;
import com.xhlj.utils.*;
import jakarta.annotation.Resource;
import kotlin.jvm.internal.Lambda;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * @author dell
 * @description 针对表【post】的数据库操作Service实现
 * @createDate 2024-03-14 15:28:14
 */
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post>
        implements PostService {
    @Resource
    private PostMapper postMapper;
    @Resource
    private CommentMapper commentMapper;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    private JwtHelper helper;

    @Override
    public Result getPostList() {

        return Result.ok(this.list());
    }

    /*
     * 分页获取全部帖子列表
     * */
    @Override
    public Result getPostPage(Integer pageSize, Integer pageNum) {
        Page<Post> page = new Page<>(pageNum, pageSize);
        this.page(page);

        return Result.ok(page.getRecords());
    }

    /*
     * 根据用户ID获取自己的帖子
     * */
    @Override
    public Result getUserPost(Integer userId) {
        LambdaUpdateWrapper<Post> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Post::getUserId, userId);
        List<Post> list = this.list(wrapper);
        return Result.ok(list);
    }

    /*
     * 根据帖子ID进行删除,同时删除盖子下面所有的评论
     * */
    @Override
    public Result deletePost(Integer postId, Integer userId) {
//        查一下是不是他发的
        LambdaQueryWrapper<Comment> commentWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Post> postLambdaQueryWrapper = new LambdaQueryWrapper<>();
        postLambdaQueryWrapper.eq(Post::getUserId, userId)
                .eq(Post::getPostId, postId);
        Post one = getOne(postLambdaQueryWrapper);
        if (one == null) {
            return Result.build(null, 400, "当前用户没有该帖子");
        } else {
            commentWrapper.eq(Comment::getPostId, one.getPostId());
            List<Comment> list = commentMapper.selectList(commentWrapper);
            int delete = commentMapper.delete(commentWrapper);
            int i = postMapper.deleteById(postId);
            for (Comment item : list) {
                clearLikeData(item.getCommentId(), postId);
                clearMessageData(item.getCommentId());

            }
            /*删除redis里的点赞记录和消息记录*/
            return Result.build(null, 200, "删除成功");
        }


    }

    /*
     * 消除评论的点赞和帖子的点赞
     * */
    private void clearLikeData(Integer commentId, Integer postId) {
        String key = RedisKey.Like_prefix + commentId;
        stringRedisTemplate.delete(key);
        key = RedisKey.Post_Like_prefix + postId;
        stringRedisTemplate.delete(key);
    }

    private void clearMessageData(Integer commentId) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        String key = RedisKey.Reply_prefix + username;
        ListOperations<String, String> ops = stringRedisTemplate.opsForList();
        List<String> commentString = ops.range(key, 0, ops.size(key) - 1);
        for (String item : commentString) {
            String id = item.substring(0, item.indexOf('|'));
            if (id.equals(commentId)) {
                ops.remove(key, 1, item);
            }
        }
    }

    /*
     * 创建帖子,感觉直接放一个html好像也没关系
     * @param Post
     * */
//    @Transactional
    @Override
    public Result createPost(Post post) {
//      todo:  校验title和content的内容
        post.setLikes(0);
        ;
        post.setViews(0);
        post.setCreatedTime(new Date());
        Post initPost = calculateHeatLevel(post);
        boolean save = this.save(initPost);
        if (save) {
            return Result.ok(null);
        }
        return Result.build(null, 400, "创建帖子失败");
    }

    /*
     * 计算帖子的热度
     * */
    @Override
    public Post calculateHeatLevel(Post post) {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        String token = stringRedisTemplate.opsForValue().get(RedisKey.Login_token_prefix + username).toString();
        PayLoad payLoad = helper.getPayLoad(token);
        double heatLevel = 0;
        UserType userType = payLoad.getUserType();
        switch (userType) {
            /*
             *
             * 热度值=(点赞量×点赞权重×用户类别权重)+(浏览量*浏览量加权系数)+(转发量*转发加权系数)
             * */
            case EXPERT -> {
                heatLevel = post.getLikes() * 5 * 5 + post.getViews();
                break;

            }
            case ONLINE -> {
                break;
            }
            case OFFLINE -> {
                break;
            }
            case STUDENT -> {
                heatLevel = post.getLikes() * 5 * 5 + post.getViews();

            }
            case GUEST -> {
                break;

            }
            default -> {
                heatLevel = post.getLikes() * 5 + post.getViews();
                break;
            }
        }
        post.setHeatLevel(heatLevel);
        return post;
    }

    /*
     * 对帖子整体进行点赞状态进行更改
     * */
    public Result addPostLikes(int postId) {
        String key = RedisKey.Post_Like_prefix + postId;
        if (stringRedisTemplate.hasKey(key)) {
            stringRedisTemplate.opsForValue().set(key, "0");

        }
        String value = stringRedisTemplate.opsForValue().get(key);
        stringRedisTemplate.opsForValue().set(key, value.equals("0") ? "1" : "0");
        LambdaQueryWrapper<Post> wrapper = new LambdaQueryWrapper();
        wrapper.eq(Post::getPostId, postId);
        Post post = postMapper.selectOne(wrapper);
        post.setLikes(value.equals("0") ? post.getLikes() + 1 : post.getLikes() - 1);
        saveOrUpdate(post);
        return Result.ok(null);
    }

    /*
     * 获取当前月份中热度最高的20条帖子
     * */
    public Result getHeatedPost() {
        Calendar calendar = new GregorianCalendar();
        int month = calendar.get(Calendar.MONTH);
        List<Post> list = postMapper.getHeatedPost();
        return Result.ok(list);
    }

}




